Communicating over a unix socket, using the socket egg

Here is a short, simple example of how you can communicate over a unix socket, using the socket egg.

NOTE: Please start the server before starting the client.

If the server has not been started first, the client will fail with this error:

 "Error: (socket-connect) cannot initiate connection - No such file or directory"

Naturally, in a real program you'd want to catch this and other potential errors, and perhaps do some fancy stuff like negotiate the message length, do partial reads with buffers, etc. All of this has been omitted from this example for the sake of clarity, focusing on doing just the bare minimum needed for low-level communication via unix sockets.

If you'd prefer a higher level interface, you may want to consider using I/O ports from the socket egg, or using the unix-sockets egg.

Server code:

;;; A short example of a server using unix sockets and the socket egg.

(use socket)

;;; Create a new unix socket:
(let ((unix-socket (socket af/unix sock/stream))
      (backlog 1) ; Length of connection queue for socket-listen call below
      (socket-pathname "foo")) ; Where to bind the socket to
  ;; Bind the file to the socket:
  (socket-bind unix-socket (unix-address socket-pathname))
  ;; Listen for incoming connections:
  (socket-listen unix-socket backlog)
  ;; Read and display a message from the client.
  (let* ((connected-socket (socket-accept unix-socket))
         (message-length 14) ; We must know the length in advance, or negotiate it.
         (received-data (socket-receive connected-socket message-length)))
    ;; Report what was read:
    (printf "Data received from the client: '~A'~%" received-data)
    ;; Cleanup:
    (socket-close connected-socket)
    (socket-close unix-socket)
    (delete-file socket-pathname)))

Client code:

;;; A short example of a client using unix sockets and the socket egg.

(use socket)

;;; Create a new unix socket:
(let* ((unix-socket (socket af/unix sock/stream))
       (pathname "foo") ; Where to bind the socket to
       (message-to-send "this is a test")) ; What to send to the server
  ;; Bind the file "foo" to the unix socket:
  (socket-connect unix-socket (unix-address pathname))
  (let ((number-of-bytes-sent (socket-send unix-socket message-to-send)))
    (printf "Number of bytes sent to the server: ~A~%" number-of-bytes-sent))
  ;; Cleanup:
  (socket-close unix-socket))